namespace SimpleWebServices.Models
{
    using System;
    using System.Collections.Generic;
    using System.Diagnostics.CodeAnalysis;
    using System.Xml.Serialization;
    using SimpleWebServices.Xml;

    [XmlRoot("publisher", Namespace = "http://www.sitemaps.org/schemas/sitemap/0.9")]
    public sealed class SiteMapPublisher : IXmlSerializerNamespaces
    {
        private static readonly Type _interface = typeof(IPublishSiteMapUrls);
        private XmlSerializerNamespaces _declarations;
        private Type _type;

        public SiteMapPublisher()
        {
            this._declarations = new XmlSerializerNamespaces();
            this._declarations.Add(string.Empty, "http://www.sitemaps.org/schemas/sitemap/0.9");
        }

        [SuppressMessage("Microsoft.Naming", "CA1721:PropertyNamesShouldNotMatchGetMethods", Justification = "This naming is intentional.")]
        [XmlIgnore]
        public Type Type
        {
            get
            {
                return this._type;
            }

            set
            {
                if (null != value)
                {
                    if (!value.Implements(_interface))
                    {
                        throw new ArgumentOutOfRangeException("value");
                    }
                }

                this._type = value;
            }
        }

        [XmlAttribute("type")]
        public string TypeValue
        {
            get
            {
                string value = null;

                if (null != this.Type)
                {
                    value = string.Concat(this.Type.FullName, ", ", this.Type.Assembly.GetName().Name);
                }

                return value;
            }

            set
            {
                Type t = null;

                if (null != value)
                {
                    if (0 == value.Length)
                    {
                        throw new ArgumentOutOfRangeException("value");
                    }

                    t = System.Type.GetType(value);
                }

                this.Type = t;
            }
        }

        [XmlNamespaceDeclarations]
        public XmlSerializerNamespaces XmlNamespaceDeclarations
        {
            get
            {
                return this._declarations;
            }

            set
            {
                this._declarations = value;
            }
        }

        public IEnumerable<SiteMapUrl> Publish()
        {
            return (Activator.CreateInstance(this.Type) as IPublishSiteMapUrls).Publish();
        }
    }
}